#include "iic.h"
#include "delay.h"
void iic_start()
{
    // SCL高电平
    SCL = 1;
    // SDA从高到低
    SDA = 1;
    // 加上延时，让单片机的执行时间应该大于设备的执行时间，保证电平翻转时间大于24c的执行时间（有时间采样）
    delay_10us(10);
    SDA = 0;
    delay_10us(10);
    // 把SCL保持在低电平，自己控制住时钟
    SCL = 0;
}

void iic_stop()
{
    // SCL高电平
    SCL = 1;
    // SDA从低到高
    SDA = 0;
    delay_10us(10);
    // 释放SDA
    SDA = 1;
}

void iic_ack(char ack)
{
    // SCL低电平，数据变化
    SCL = 0;
    delay_10us(10);
    SDA = ack;
    // 放弃时钟，让从机读取应答
    delay_10us(10);
    SCL = 1;

    // 把SCL保持在低电平，自己控制住时钟
    SCL = 0;
}

void iic_write(unsigned char sda_data)
{
    // SCL低电平，数据变化
    SCL = 0;
    // 从高位开始发送
    for (i = 0; i < 8; i++)
    {
        SDA = sda_data & (0x80 >> i);
        delay_10us(10);
        // 释放时钟，从机读取
        SCL = 1;
        delay_10us(10);
        // 钳住SCL低电平，自己控制住时钟
        SCL = 0;
        delay_10us(5);
    }
}

unsigned char iic_read(int ack)
{
    unsigned char sda_data = 0x00;
    // 主机释放SDA
    SCL = 0;
    SDA = 1;
    // 从机在此时开始写SDA
    for (i = 0; i < 8; i++)
    {
        // 拉高SCL，此时从机写完了SDA，SDA电平在高电平期间不会变
        SCL = 1;
        delay_10us(10);
        if (SDA)
        {
            sda_data |= (0x80 >> i);
        }
        // 钳住SCL低电平，进入下一个脉冲周期，从机开始写SDA
        SCL = 0;
        delay_10us(10);
    }
    // 发送应答
    iic_ack(ack);
    return sda_data;
}

int iic_wait_ack()
{
    // 先释放SDA，让从机写应答
    SCL = 0;
    SDA = 1;
    // SCL高电平，此时从机已经写完，高电平期间SDA不会变化
    SCL = 1;
    delay_10us(10);
    int temcount = 0;
    while (temcount < 200)
    {
        temcount++;
    }
    int ack = SDA;
    // 钳住SCL低电平
    SCL = 0;
    return ack;
}